#include<iostream>
#include<vector>
#include<string>
#include <boost/filesystem.hpp>
#include"util.hpp"
#include<fstream>
const std::string src_path = "data/input";
const std::string output = "data/output/raw.txt";
struct DocInfo
{
    std::string title;
    std::string content;
    std::string url;

};
void ShowDoc( const DocInfo &doc)
{
    std::cout << "title: " << doc.title << std::endl;
    std::cout << "content: " << doc.content << std::endl;
    std::cout << "url: " << doc.url << std::endl;
}
//我们只要.html文件
bool EnumFiles(const std::string& file_path,std::vector<std::string>* files_name)
{
    namespace fs = boost::filesystem;
    if(!fs::is_directory(file_path))
    {
        std::cerr<<file_path << "is not a dir!"<<std::endl;
        return false;
    }
    //检查是不是文件且文件的拓展名是.html
    else
    {
        fs::recursive_directory_iterator end;
        for(fs::recursive_directory_iterator iter(file_path);iter != end;++iter)
        {
            if(iter->path().extension() != ".html")
            {
                continue;
            }
            files_name->push_back(iter->path().string());
        }
        return true;
    }
}
bool ParseTitle(const std::string& result,std::string* title)
{
    //查找头部位子
    int begin = result.find("<title>");
    if(begin == std::string::npos)
    {
        return false;
    }
    int end = result.find("</title>");
    if(end == std::string::npos)
    {
        return false;
    }
    if(begin > end)
    {
        return false;
    }
    begin += std::string("<title>").size();
    *title = result.substr(begin,end-begin);
    return true;
}
bool ParseContent(const std::string& result,std::string* content)
{
    //使用简易状态机
    enum STATUS
    {
        LABLE,
        CONTENT
    };
    enum STATUS s;
    s = LABLE;
    for(char c: result)
    {
        switch (s)
        {
        case LABLE:
            if(c == '>')
            {
                s = CONTENT;
            }
            break;
        case CONTENT:
            if(c == '<')
            {
                s = LABLE;
            }
            else
            {
                if(c == '\n')
                {
                    c = ' ';
                }
                content->push_back(c);
            }
            break;
        default:
            break;
        }
    }
    return true;
}
bool ParseUrl(const std::string& file_path,std::string* url)
{
    std::string url_head = "https://www.boost.org/doc/libs/1_84_0/doc/html";
    std::string url_tail = file_path.substr(src_path.size());
    *url = url_head + url_tail;
    return true;
}
bool ParseFile(std::vector<std::string>files_name,std::vector<DocInfo>* pdoc)
{
    for(auto file_name : files_name)
    {
        std::string result;
        //先把文件内容读取出来
        if(!ns_util::FileUtil::ReadFile(file_name,&result))
        {
            continue;
        }
        DocInfo doc;
        if(!ParseTitle(result,&doc.title))
        {
            continue;
        }
        if(!ParseContent(result,&doc.content))
        {
            continue;
        }
        if(!ParseUrl(file_name,&doc.url))
        {
            continue;
        }
        // ShowDoc(doc);
        pdoc->push_back(doc);
    }
    return true;
}
bool SaveFile(const std::vector<DocInfo>& doc,const std::string& output)
{
    #define SEP '\3'
    std::ofstream out(output,std::ios::out|std::ios::binary);
    if(!out.is_open())
    {
        std::cerr<<"open file error" << std::endl;
        return false;
    }
    for(auto& item : doc)
    {
        std::string line;
        line += item.title;
        line += SEP;
        line += item.content;
        line += SEP;
        line += item.url;
        line += "\n";
        out.write(line.c_str(),line.size());
    }
    out.close();
    return true;
}
int main()
{
    std::vector<std::string>files_name;
    if(!EnumFiles(src_path,&files_name))
    {
        std::cerr<<"enumfile error !"<<std::endl;
        return 1;
    }
    // std::cout<<files_name.size()<<std::endl;
    //根据读取的文件名读取文件内容
    std::vector<DocInfo>doc;
    if(!ParseFile(files_name,&doc))
    {
        std::cerr<<"Parse file error !"<<std::endl;
        return 2;
    }
    //保存到文件中，
    if(!SaveFile(doc,output))
    {
        std::cerr<<"Save File error ! "<<std::endl;
        return 3;
    }
    // std::cout<<"aaaaa"<<std::endl;
    return 0;
}